#include "minunit.h"
#include <lcthw/linklist.h>
#include <assert.h>

static void node_print(LinkList node)
{
    printf("This node contains: %d\n", node->data);
}   

static LinkList list = NULL;

char *test_create()
{
    list = Init_List();
    mu_assert(list != NULL, "Failed to create list");

    return NULL;
}

char *test_destroy()
{
    Destroy_List(list);

    return NULL;
}

char *test_clear()
{
    Clear_List(list);

    return NULL;
}

char *test_empty()
{
    mu_assert(List_Empty(list) == 1, "List should be empty");

    return NULL;
}

char *test_length()
{
    Clear_List(list);
    mu_assert(List_Length(list) == 0, "List should have length 0");
    List_Insert(list, 1, 1);
    mu_assert(List_Length(list) == 1, "List should have length 1");
    List_Insert(list, 2, 2);
    mu_assert(List_Length(list) == 2, "List should have length 2");
    return NULL;
}

char *test_insert()
{
    Clear_List(list);
    List_Insert(list, 1, 1);
    mu_assert(list->next->data == 1, "Failed to insert 1");
    List_Insert(list, 2, 2);
    mu_assert(list->next->next->data == 2, "Failed to insert 2");
    List_Insert(list, 1, 3);
    mu_assert(list->next->data == 3, "Failed to insert 3");
    List_Traverse(list, node_print);
    return NULL;
}

char *test_delete()
{
    ElemType e;
    Clear_List(list);
    List_Insert(list, 1, 1);
    List_Insert(list, 2, 2);
    List_Insert(list, 3, 3);
    List_Delete(list, 2, &e);
    mu_assert(e == 2, "Failed to delete 2");
    List_Delete(list, 1, &e);
    mu_assert(e == 1, "Failed to delete 1");
    List_Delete(list, 1, &e);
    mu_assert(e == 3, "Failed to delete 3");
    return NULL;
}

char *test_traverse()
{
    Clear_List(list);
    List_Insert(list, 1, 1);
    List_Insert(list, 2, 2);
    List_Insert(list, 3, 3);
    List_Traverse(list, node_print);
    return NULL;
}

char *all_tests()
{
    mu_suite_start();

    mu_run_test(test_create);
    mu_run_test(test_empty);
    mu_run_test(test_length);
    mu_run_test(test_insert);
    mu_run_test(test_delete);
    mu_run_test(test_traverse);
    mu_run_test(test_destroy);
    return NULL;
}

RUN_TESTS(all_tests);